package com.xuanner.dt.client;

import com.xuanner.dt.common.DtCloseable;

import java.util.Collection;
import java.util.Map;

/**
 * 所有分布式组件的核心Client，主要提供了set、get、del、incr等分布式操作
 * 注意注意注意：该类线程不安全，如果要多线程操作，请先自己加同步锁
 * Created by xuan on 2018/8/10.
 */
public interface DtClient extends DtCloseable {

    /**
     * 单个删除key
     *
     * @param key key
     */
    void del(String key);

    /**
     * 批量删除key
     *
     * @param keys
     */
    void delBulk(Collection<String> keys);

    /**
     * 单个设置KV
     *
     * @param key     key
     * @param value   value
     * @param seconds 过期时间，单位：秒
     */
    void set(String key, String value, int seconds);

    /**
     * 批量设置KV
     *
     * @param map     KV的MAP集合
     * @param seconds 过期时间，单位：秒
     */
    void setBulk(Map<String, String> map, int seconds);

    /**
     * 设置KV，如果不存在就set，返回成功1，如果已存在不做任何操作，返回0
     *
     * @param key   key
     * @param value value
     * @return 1设置成功，0未设置（表示key已经存在）
     */
    Long setIfAbsent(String key, String value);

    /**
     * 单个获取值
     *
     * @param key key
     * @return value
     */
    String get(String key);

    /**
     * 批量获取值
     *
     * @param keys keys
     * @return 值MAP
     */
    Map<String, String> getBulk(Collection<String> keys);

    /**
     * Long类型原子增长
     *
     * @param key key
     * @param l   增长幅度
     * @return 增长后的值
     */
    Long incrByLong(String key, long l);

    /**
     * Long类型原子减
     *
     * @param key key
     * @param l   减幅度
     * @return 减后的值
     */
    Long decrByLong(String key, long l);

    /**
     * Double类型原子增长
     *
     * @param key key
     * @param d   增长幅度
     * @return 增长后的值
     */
    Double incrByDouble(String key, double d);

    /**
     * 判断值是否存在
     *
     * @param key key
     * @return true/false
     */
    Boolean exists(String key);

    /**
     * 发送一条消息到一个topic
     *
     * @param topic   topic
     * @param message 消息
     */
    void publish(String topic, String message);

    /**
     * 订阅
     *
     * @param subCallback 收到通知回调
     * @param topics      topic
     */
    void subcribe(SubCallback subCallback, String... topics);

    /**
     * 列表左边添加元素
     *
     * @param listName 列表名称
     * @param elements 元素
     * @return 添加后列表的长度
     */
    long listPushLeft(String listName, String... elements);

    /**
     * 在列表右边弹出一个元素
     *
     * @param listName 列表名称
     * @return 弹出的元素，如果列表是空，返回null
     */
    String listPopRight(String listName);

    /**
     * 在列表右边弹出一个元素
     *
     * @param listName 列表名称
     * @param timeout  超时时间
     * @return 弹出的元素
     */
    String listPopRightBlock(String listName, int timeout);

    /**
     * 返回列表的长度
     *
     * @param listName 列表名称
     * @return 长度
     */
    long listLength(String listName);
}
